KVC与KVO

##KVC与KVO

###KVC(key-value-coding)键值编码
用来给一个对象的属性进行赋值或者访问.
通过类别的方式添加
@interface NSObject(NSKeyValueCoding)

使用:

  • (void)setValue:(nullable id)value forKey:(NSString *)key;
    • (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
      第二个方法通过路径的方式的访问,即可以访问成员变量是对象的属性 “Dog.age”

应用:

  1. 系统Storyboard控件拖线
  2. 访问私有成员变量
  3. 字典转模型

字典转模型(属性名相同,不能是关键字,嵌套对象模型时还需另做处理,一般使用第三方)

  • (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;
    遇到不能识别的key执行的方法
  • (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;

原理:

###KVO(key-value-observing)键值监听
利用一个key来找到某个属性并监听其值的改变。典型的观察者模式
类别:@interface NSObject(NSKeyValueObserving)

使用:

  1. 添加监听
  2. 实现监听方法,observeValueForKeyPath: ofObject: change: context:
  3. 移除监听

相关API

  • (void)addObserver:(NSObject )observer forKeyPath:(NSString )keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;//添加监听
  • (void)removeObserver:(NSObject )observer forKeyPath:(NSString )keyPath context:(nullable void *)context API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));//删除监听
  • (void)removeObserver:(NSObject )observer forKeyPath:(NSString )keyPath;//删除监听
  • (void)observeValueForKeyPath:(nullable NSString )keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> )change context:(nullable void *)context;//监听实现方法

####手动实现KVO
重写该方法,对应的key但会NO

  • (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key;
    调用方法完成当值改变时发出通知
  • (void)willChangeValueForKey:(NSString *)key;
  • (void)didChangeValueForKey:(NSString *)key;

###KVO的实现原理
当一个类的属性被观察的时候,系统会通过runtime动态的创建一个该类的派生类,并且会在这个类中重写基类被观察的属性的setter方法,而且系统将这个类的isa指针指向了派生类,从而实现了给监听的属性赋值时调用的是派生类的setter方法。重写的setter方法会在调用原setter方法前后,通知观察对象值得改变。